package tr.com.netgis.util;

import java.util.Collections;
import java.util.List;

import tr.com.netgis.NGApplication;
import tr.com.netgis.db.NGDbHelper;
import tr.com.netgis.pojo.NGLocation;
import android.util.Log;


public abstract class AStatusSpeedStrategy implements StatusSpeedStrategy {

	public AStatusSpeedStrategy(RotatingNGLocation locations) {
		super();
	}
	
	public AStatusSpeedStrategy() {
		super();
	}
	
	@Override
	public Status determineStatus(NGLocation currentLocation, RotatingNGLocation rLocations) {
		List<NGLocation> locations = rLocations.toList();
		Collections.sort(locations);

		if (locations.size() == 0)
			return Status.DURDU;
		
		//hızları zaten, önceden ortalamaya göre hesaplıyoruz
		if (currentLocation.getSpeed() < Constants.eV)
			return Status.DURDU;
		else {
			return Status.HAREKET_EDIYOR;
		}
	}
	
	/**
	 * şimdilik hız hesaplama bir önceki konuma göre yapılacak Last2Location gibi yapılıyor
	 */
	@Override
	public float calculateSpeed(NGLocation currentLocation, RotatingNGLocation rLocations) {
		//List<NGLocation> locations = rLocations.toList();
		//NGLocation previousLocation = getPreviousLocation(currentLocation, locations);
		
		/**
		 * If location is retrieved from network provider 
		 * search for previous location that was retrieved one hour ago
		 */
		NGLocation previousLocation = null;
		NGDbHelper helper = null;
		if (currentLocation.isNetwork()) {
			try {
				helper = new NGDbHelper(NGApplication.getAppContext());
				previousLocation = helper.getLocationBeforeByMinute(currentLocation, 30);				
			} catch (Exception e) {
				Log.d("NG_DB", "Failed while getLocationBeforeByMinute", e);
			} finally {
				if (helper != null) {
					helper.close();
				}
			}
		} else {
			previousLocation = rLocations.getLastInstertedElement();			
		}
		
		if (previousLocation == null) {
			return 0;
		}
		return Utility.speed(previousLocation, currentLocation);
	}
	
	protected NGLocation getPreviousLocation (NGLocation currentLocation, List<NGLocation> locations) {
		if (Utility.isEmpty(locations))
			return null;
		Collections.sort(locations);
		/*
		for (int i = locations.size() - 1 ; i >= 0; i--) {
			if (locations.get(i).equals(currentLocation))
				continue;
			return locations.get(i);
		}
		return null;
		*/
		return locations.get(locations.size()-1);
	}
	
	/**
	 * Locations' speed property must be set before.
	 * @param currentLocation
	 * @param locations
	 * @return
	 */
	protected boolean stopped (NGLocation currentLocation, List<NGLocation> locations){
		boolean durdu = true;
		int n = locations.size();
		float eV = Constants.eV;
		if (n > 3) {
		     for (int i = 0; i < n; i++) {
		         if (locations.get(i).getSpeed() > eV) {
		              durdu = false;
		              break;
		         }
		     }
		 
		     float vAvarage = Utility.speed(locations.get(0), locations.get(n - 1));
		     
		     if (vAvarage > eV) {
		    	 durdu = false;
		     }
		} else {
		     //son konuma bak, yani sunucuya post edilecek konum bilgisine
		     durdu = currentLocation.getSpeed() < eV;
		}		
		return durdu;
	}
	
}
